/**
 * @file lv_port_indev_templ.c
 *
 */

/*********************
 *      INCLUDES
 *********************/
#include "lv_port.h"
#ifdef CONFIG_SDL2_LCD
#include "input/sdl2_tp.h"

static sdl2_tp tp;

static void touchpad_init(void);
static void touchpad_read(lv_indev_t* indev, lv_indev_data_t* data);
static bool touchpad_is_pressed(void);
static void touchpad_get_xy(int32_t* x, int32_t* y);

lv_indev_t* indev_touchpad;
#endif

#ifdef CONFIG_LV_USE_EVDEV
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static char get_event_number(const char *device_name);
#endif

void lv_port_indev_init(void)
{
	/*------------------
	 * Touchpad
	 * -----------------*/
#ifdef CONFIG_SDL2_LCD
	/*Initialize your touchpad if you have*/
	touchpad_init();

	/*Register a touchpad input device*/
	indev_touchpad = lv_indev_create();
	lv_indev_set_type(indev_touchpad, LV_INDEV_TYPE_POINTER);
	lv_indev_set_read_cb(indev_touchpad, touchpad_read);
#endif
#ifdef CONFIG_LV_USE_EVDEV
	char evdev[20];
	char num;
	struct screen screen;

	screen = get_screen();

	num = get_event_number("mouse0");
	if (num < 0) {
		perror("cat not get mouse\n");
		return;
	}

	sprintf(evdev, "/dev/input/event%c", num);

	// 初始化Inpu输入子系统. 这里需要设置
	lv_indev_t* cdev = lv_evdev_create(LV_INDEV_TYPE_POINTER, evdev);
//	lv_evdev_set_swap_axes(cdev, true);  // 设置xy交换翻转
	lv_evdev_set_calibration(cdev, 0, 0, screen.x, screen.y);  // 设置触摸最大范围和最小范围

	LV_IMG_DECLARE(mouse_cursor_icon);                           /*  声明图片源   */
	lv_obj_t *cursor_obj = lv_image_create(lv_screen_active());    /*  为光标创建一个图片对象  */
	lv_image_set_src(cursor_obj, &mouse_cursor_icon);            /*  设置图片源  */
	lv_indev_set_cursor(cdev, cursor_obj);                /*  将图片对象与驱动程序连接  */
#endif
}

#ifdef CONFIG_LV_USE_EVDEV
static char get_event_number(const char *device_name)
{
	FILE *fp;
	char line[256];

	fp = fopen("/proc/bus/input/devices", "r");
	if (fp == NULL) {
		perror("Failed to open /proc/bus/input/devices");
		return -1;
	}

	while (fgets(line, sizeof(line), fp)) {
		if (strstr(line, device_name)) {
			char *start = strstr(line, "event");
			if (start) {
				fclose(fp);
				return *(start + 5);
			}
		}
	}
	fclose(fp);
	return -1;
}
#endif

void lv_port_indev_event_poll(void)
{
#ifdef CONFIG_SDL2_LCD
	sdl2_tp_event_poll(&tp);
#endif
}

bool lv_port_indev_quit(void)
{
#ifdef CONFIG_SDL2_LCD
	return sdl2_tp_quit_get(&tp);
#else
	return 0;
#endif
}

#ifdef CONFIG_SDL2_LCD
/*------------------
 * Touchpad
 * -----------------*/

/*Initialize your touchpad*/
static void touchpad_init(void)
{
	sdl2_tp_init(&tp);
}

/*Will be called by the library to read the touchpad*/
static void touchpad_read(lv_indev_t* indev_drv, lv_indev_data_t* data)
{
	static int32_t last_x = 0;
	static int32_t last_y = 0;

	/*Save the pressed coordinates and the state*/
	if (touchpad_is_pressed()) {
		touchpad_get_xy(&last_x, &last_y);
		data->state = LV_INDEV_STATE_PR;
	} else {
		data->state = LV_INDEV_STATE_REL;
	}

	/*Set the last pressed coordinates*/
	data->point.x = last_x;
	data->point.y = last_y;
}

/*Return true is the touchpad is pressed*/
static bool touchpad_is_pressed(void)
{
	return sdl2_tp_is_pressed(&tp);
}

/*Get the x and y coordinates if the touchpad is pressed*/
static void touchpad_get_xy(int32_t* x, int32_t* y)
{
	/**
	 * 由于数据类型不一致
	 * lvgl 是 lv_coord_t 类型，对于 RGB565 来说，其实就是 uint16_t
	 * sdl2_tp 是 int 类型
	 * 防止出现连续内存赋值导致数据覆盖的问题，索性用一个临时变量缓存下
	 */
	int tmpx = 0;
	int tmpy = 0;
	sdl2_tp_get_xy(&tp, &tmpx, &tmpy);

	*x = tmpx;
	*y = tmpy;
}
#endif
